home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / Macintosh Tracker 1.1 Source / Original Tracker 3.10 Source / player.c < prev    next >
Text File  |  1993-05-22  |  9KB  |  400 lines

  1. /* player.c */
  2.  
  3. /* $Id: player.c,v 3.9 1993/04/25 14:08:15 espie Exp espie $
  4.  * $Log: player.c,v $
  5.  * Revision 3.9  1993/04/25  14:08:15  espie
  6.  * Bug fix: now use correct finetune when loading samples/starting notes.
  7.  *
  8.  * Revision 3.8  1993/01/15  14:00:28  espie
  9.  * Added bg/fg test.
  10.  *
  11.  * Revision 3.7  1993/01/06  17:58:39  espie
  12.  * *** empty log message ***
  13.  *
  14.  * Revision 3.6  1992/11/27  10:29:00  espie
  15.  * General cleanup
  16.  *
  17.  * Revision 3.5  1992/11/24  10:51:19  espie
  18.  * un#ifdef'ed showseq code.
  19.  *
  20.  * Revision 3.4  1992/11/23  10:12:23  espie
  21.  * *** empty log message ***
  22.  *
  23.  * Revision 3.3  1992/11/22  17:20:01  espie
  24.  * Added <> operators.
  25.  * Added update frequency on the fly.
  26.  *
  27.  * Revision 3.2  1992/11/20  14:53:32  espie
  28.  * Added finetune.
  29.  *
  30.  * Revision 3.1  1992/11/19  20:44:47  espie
  31.  * Protracker commands.
  32.  *
  33.  * Revision 3.0  1992/11/18  16:08:05  espie
  34.  * New release.
  35.  *
  36.  * Revision 2.19  1992/11/17  17:15:37  espie
  37.  * Added interface using may_getchar(). Still primitive, though.
  38.  * imask, start.
  39.  * Added transpose feature.
  40.  * Added possibility to get back to MONO for the sgi.
  41.  * Added stereo capabilities to the indigo version.
  42.  * Added two level of fault tolerancy.
  43.  * Added some control on the number of replays,
  44.  * and better error recovery.
  45.  */
  46.      
  47. #include <stdio.h>
  48.      
  49. #include "defs.h"
  50. #include "extern.h"
  51. #include "song.h"
  52. #include "channel.h"
  53. #include "pref.h"
  54.      
  55. LOCAL BOOL show;
  56.  
  57. LOCAL char *num[] = {
  58. " 0", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9",
  59. "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
  60. "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
  61. "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
  62. "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
  63. "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
  64. "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
  65. "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
  66. "80", "81", "82", "83", "84", "85", "86", "87", "88", "89"};
  67.  
  68. LOCAL char *cmdname[] = {
  69. "arp", "dwn", "up ", "prt", "vib", "pts", "vbs", "7  ", "8  ", "off", "svl", 
  70. "ff ", "vol", "skp", "ext", "spd"};
  71.  
  72. LOCAL char *id = "$Id: player.c,v 3.9 1993/04/25 14:08:15 espie Exp espie $";
  73.      
  74.  
  75. /* init_channel(ch, dummy):
  76.  * setup channel, with initially
  77.  * a dummy sample ready to play,
  78.  * and no note.
  79.  */
  80. LOCAL void init_channel(ch, dummy)
  81. struct channel *ch;
  82. struct sample_info *dummy;
  83.     {
  84.     ch->samp = dummy;
  85.     ch->finetune = ch->samp->finetune;
  86.     ch->mode = DO_NOTHING; 
  87.     ch->pointer = 0; 
  88.     ch->step = 0; 
  89.     ch->volume = 0; 
  90.     ch->pitch = 0; 
  91.     ch->note = NO_NOTE;
  92.  
  93.         /* we don't setup arpeggio values. */
  94.     ch->viboffset = 0; 
  95.     ch->vibdepth = 0;
  96.  
  97.     ch->slide = 0; 
  98.  
  99.     ch->pitchgoal = 0; 
  100.     ch->pitchrate = 0;
  101.  
  102.     ch->volumerate = 0;
  103.  
  104.     ch->vibrate = 0;
  105.     ch->adjust = do_nothing;
  106.     }
  107.  
  108.  
  109.  
  110. LOCAL int VSYNC;          /* base number of sample to output */
  111. void (*eval[NUMBER_EFFECTS])();
  112.                     /* the effect table */
  113. LOCAL int oversample;     /* oversample value */
  114. LOCAL int frequency;      /* output frequency */
  115. LOCAL int channel;        /* channel loop counter */
  116.  
  117. LOCAL struct channel chan[NUMBER_TRACKS];
  118.                     /* every channel */
  119. LOCAL int countdown;      /* keep playing the tune or not */
  120.  
  121. LOCAL struct song_info *info;
  122. LOCAL struct sample_info *voices;
  123.  
  124. LOCAL struct automaton a;
  125.  
  126.  
  127. void init_player(o, f)
  128. int o, f;
  129.     {
  130.     oversample = o;
  131.     frequency = f;
  132.     init_tables(o, f, NULL);
  133.     init_effects(eval);
  134.     }
  135.  
  136. LOCAL void dump_event(ch, e, imask)
  137. struct channel *ch;
  138. struct event *e;
  139. unsigned long imask;
  140.     {
  141.     int samp;
  142.     int cmd;
  143.  
  144.     if (!run_in_fg())
  145.         return;
  146.     samp = e->sample_number;
  147.     cmd = e->effect;
  148.     if (samp == 0 && e->pitch == 0 && cmd == 0)
  149.         printf("                 ");
  150.     else
  151.         {
  152.         if (samp)
  153.             printf("%s ", num[samp]);
  154.         else
  155.             printf("   ");
  156.         if (((samp != 0) && ((1L<<samp) & imask)) 
  157.             || ((samp == 0) && (ch->samp == voices)))
  158.             printf("             ");
  159.         else
  160.             {
  161.             if (e->note != NO_NOTE)
  162.                 printf("%s ", note_name[e->note]);
  163.             else
  164.                 printf("    ");
  165.             if (e->effect == 0 && e->parameters == 0)
  166.                 printf("          ");
  167.             else
  168.                 switch(cmd)
  169.                     {
  170.                 case 10:
  171.                     printf("%s %3d   ", cmdname[cmd], 
  172.                         HI(e->parameters) - LOW(e->parameters));
  173.                     break;
  174.                 case 14:
  175.                     printf("%s %2d/%2d ", cmdname[cmd], 
  176.                         HI(e->parameters), LOW(e->parameters));
  177.                     break;
  178.                 default:
  179.                     printf("%s %3d   ", cmdname[cmd], e->parameters);
  180.                     }
  181.             }
  182.         }
  183.     fflush(stdout);
  184.     }
  185.  
  186. LOCAL void setup_effect(ch, a, e, imask, bcdvol)
  187. struct channel *ch;
  188. struct automaton *a;
  189. struct event *e;
  190. unsigned long imask;
  191. int bcdvol;
  192.     {
  193.     int samp, cmd;
  194.  
  195.         /* retrieves all the parameters */
  196.     samp = e->sample_number;
  197.  
  198.         /* load new instrument */
  199.     if (samp)  
  200.         {
  201.             /* note that we can change sample in the middle
  202.              * of a note. This is a *feature*, not a bug (see
  203.              * made). Precisely: the sampel change will be taken
  204.              * into account for the next note, BUT the volume change
  205.              * takes effect immediately.
  206.              */
  207.         ch->samp = voices + samp;
  208.         ch->finetune = voices[samp].finetune;
  209.         if ((1L<<samp) & imask)
  210.             ch->samp = voices;
  211.         set_current_volume(ch, voices[samp].volume);
  212.         }
  213.  
  214.     a->note = e->note;
  215.     if (a->note != NO_NOTE)
  216.         a->pitch = pitch_table[a->note][ch->finetune];
  217.     else
  218.         a->pitch = e->pitch;
  219.     cmd = e->effect;
  220.     a->para = e->parameters;
  221.  
  222.     if (a->pitch >= MAX_PITCH)
  223.         {
  224.         fprintf(stderr, "Pitch out of bounds %d\n", a->pitch);
  225.         a->pitch = 0;
  226.         error = FAULT;
  227.         }
  228.     if (cmd == 12 && bcdvol)
  229.         a->para = HI(a->para)*10+LOW(a->para);
  230.  
  231.     if (show)
  232.         dump_event(ch, e, imask);
  233.         /* check for a new note: cmd 3/5 (portamento)
  234.          * is the special case where we do not restart
  235.          * the note.
  236.          */
  237.     if (a->pitch && cmd != 3 && cmd != 5)
  238.         reset_note(ch, a->note, a->pitch);
  239.     ch->adjust = do_nothing;
  240.         /* do effects */
  241.     (eval[cmd])(a, ch);
  242.     }
  243.  
  244.  
  245. LOCAL void adjust_sync(ofreq, tempo)
  246. int ofreq, tempo;
  247.     {
  248.     VSYNC = ofreq * NORMAL_FINESPEED / tempo;
  249.     }
  250.  
  251. LOCAL void play_once(a, pref)
  252. struct automaton *a;
  253. struct pref *pref;
  254.     {
  255.     int channel;
  256.  
  257.     if (a->do_stuff & DELAY_PATTERN)
  258.         for (channel = 0; channel < NUMBER_TRACKS; channel++)
  259.             /* do the effects */
  260.             (chan[channel].adjust)(chan + channel);
  261.     else
  262.         {    
  263.         for (channel = 0; channel < NUMBER_TRACKS; channel++)
  264.             if (a->counter == 0)
  265.                 /* setup effects */
  266.                 setup_effect(chan + channel, a, 
  267.                     &(a->pattern->e[channel][a->note_num]), 
  268.                     pref->imask, pref->bcdvol);
  269.             else
  270.                 /* do the effects */
  271.                 (chan[channel].adjust)(chan + channel);
  272.         }
  273.  
  274.         /* advance player for the next tick */
  275.     next_tick(a);
  276.         /* actually output samples */
  277.     resample(chan, oversample, VSYNC / a->finespeed);
  278.     }
  279.  
  280.  
  281.  
  282. void play_song(song, pref, start)
  283. struct song *song;
  284. struct pref *pref;
  285. int start;
  286.     {
  287.     int tempo;
  288.  
  289.     tempo = pref->speed;
  290.     show = pref->show;
  291.  
  292.     adjust_sync(frequency, tempo);
  293.     /* a repeats of 0 is infinite replays */
  294.     if (pref->repeats)
  295.         countdown = pref->repeats;
  296.     else
  297.         countdown = 1;
  298.  
  299.     info = &song->info;
  300.     voices = song->samples; 
  301.  
  302.     init_automaton(&a, song, start, pref->show);
  303.  
  304.     for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  305.         init_channel(chan + channel, voices);
  306.  
  307.  
  308.     while(countdown)
  309.         {
  310.         play_once(&a, pref);
  311.         switch(may_getchar())
  312.             {
  313.         case 'n':
  314.             discard_buffer();
  315.             error = NEXT_SONG;
  316.             return;
  317.         case 'p':
  318.             discard_buffer();
  319.             error = PREVIOUS_SONG;
  320.             return;
  321.         case 'x':
  322.         case 'e':
  323.         case 'q':
  324.             discard_buffer();
  325.             end_all();
  326.         case 's':
  327.             tempo = 50;
  328.             adjust_sync(frequency, tempo);
  329.             break;
  330.         case 'S':
  331.             tempo = 60;
  332.             adjust_sync(frequency, tempo);
  333.             break;
  334.         case 'r':
  335.             discard_buffer();
  336.             init_automaton(&a, song, start, pref->show);
  337.             for (channel = 0; channel < NUMBER_TRACKS; channel++) 
  338.                 init_channel(chan + channel, voices);
  339.             break;
  340.         case '>':
  341.             discard_buffer();
  342.             init_automaton(&a, song, a.pattern_num+1, pref->show);
  343.             break;
  344.         case '<':
  345.             discard_buffer();
  346.             if (a.note_num < 4)
  347.                 init_automaton(&a, song, a.pattern_num -1, pref->show);
  348.             else
  349.                 init_automaton(&a, song, a.pattern_num, pref->show);
  350.             break;
  351.         case '?':
  352.             dump_song(song);
  353.             break;
  354.         case ' ':
  355.             while (may_getchar() == EOF)
  356.                 ;
  357.             break;
  358.         default:
  359.             break;
  360.             }
  361.         {
  362.         int new_freq;
  363.         if (new_freq = update_frequency())
  364.             {
  365.             frequency = new_freq;
  366.             adjust_sync(frequency, tempo);
  367.             init_tables(oversample, frequency, chan);
  368.             }
  369.         }
  370.  
  371.         switch(error)
  372.             {
  373.         case NONE:
  374.             break;
  375.         case ENDED:
  376.             if (pref->repeats)
  377.                 countdown--;
  378.             break;
  379.         case SAMPLE_FAULT:
  380.             if (!pref->tolerate)
  381.                 countdown = 0;
  382.             break;
  383.         case FAULT:
  384.             if (pref->tolerate < 2)
  385.                 countdown = 0;
  386.             break;
  387.         case PREVIOUS_SONG:
  388.         case NEXT_SONG:
  389.         case UNRECOVERABLE:
  390.             countdown = 0;
  391.             break;
  392.         default:
  393.             break;
  394.             }
  395.         error = NONE;
  396.         }
  397.          
  398.     }
  399.  
  400.